package com.alarmtoexercise.alarm;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import com.alarmtoexercise.R;
import com.alarmtoexercise.alarm.AlarmProcessor;
import com.alarmtoexercise.util.Tools;

/**
 * AlarmClock application.
 */
public class AlarmClock extends Activity implements OnItemClickListener {

	private final static String LOG_CLASS = "AlarmClock";

	static final String PREFERENCES = "AlarmClock";

	/** Cap alarm count at this number */
	static final int MAX_ALARM_COUNT = 4;
	private AlarmAdapter alarmAdapter;
	private SharedPreferences mPrefs;
	private Cursor mCursor;
	private ListView mAlarmsList;
	private LayoutInflater inflater;
	private ImageView addAlarmButton;
	private Context context = this;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mPrefs = getSharedPreferences(PREFERENCES, 0);

		inflater = LayoutInflater.from(this);
		setContentView(R.layout.alarm_clock);

		setUI();
		updateLayout();
	}

	private void setUI() {
		mAlarmsList = (ListView) findViewById(R.id.alarms_list);
		addAlarmButton = (ImageView) findViewById(R.id.ic_add);	
		
		alarmAdapter = new AlarmAdapter();

		mAlarmsList.setAdapter(alarmAdapter);
		mAlarmsList.setOnItemClickListener(this);
		mAlarmsList.setOnCreateContextMenuListener(this);

		findViewById(R.id.digitalClock).setOnClickListener(
				new OnClickListener() {

					@Override
					public void onClick(View v) {
						updateLayout();

					}
				});

		findViewById(R.id.ic_settings).setOnClickListener(
				new OnClickListener() {

					@Override
					public void onClick(View v) {
						startActivity(new Intent(context, SettingsActivity.class));
					}
				});
	}

	public void updateLayout() {
		mCursor = AlarmProcessor.getAlarmsCursor(getContentResolver());
		alarmAdapter.updateCursor(mCursor);
		
		addAlarmButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if(mAlarmsList.getAdapter().getCount() < MAX_ALARM_COUNT){
					addAlarm();
				}else{
					Toast.makeText(context, context.getString(R.string.alarm_alert_toomany, MAX_ALARM_COUNT), Toast.LENGTH_LONG).show();
				}
				
			}

		});
	}

	@Override
	protected void onResume() {
		updateLayout();
		super.onResume();
	}

	private void addAlarm() {
		Uri uri = AlarmProcessor.addAlarm(getContentResolver());
		// TODO: Create new alarm _after_ SetAlarm so the user has the
		// chance to cancel alarm creation.
		String segment = uri.getPathSegments().get(1);
		int newId = Integer.parseInt(segment);
		if (Tools.DEBUG) {
			Log.v(LOG_CLASS, "In AlarmClock, new alarm id = " + newId);
		}
		Intent intent = new Intent(this, SetAlarm.class);
		intent.putExtra(AlarmProcessor.ALARM_ID, newId);
		startActivity(intent);
	}

	private final Handler mHandler = new Handler();
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Send a message to avoid a possible ANR.
		mHandler.post(new Runnable() {
			public void run() {
				setUI();
			}
		});
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		com.alarmtoexercise.util.ToastMaster.cancelToast();
	}

	@Override
	public void onItemClick(AdapterView parent, View v, int pos, long id) {
		Intent intent = new Intent(this, SetAlarm.class);
		intent.putExtra(AlarmProcessor.ALARM_ID, (int) id);
		startActivity(intent);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View view,
			ContextMenuInfo menuInfo) {
		// Inflate the menu from xml.
		getMenuInflater().inflate(R.menu.context_menu, menu);

		// Use the current item to create a custom view for the header.
		final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
		final Cursor c = (Cursor) mAlarmsList.getAdapter().getItem(
				(int) info.position);
		final AlarmObject alarm = new AlarmObject(c);

		// Construct the Calendar to compute the time.
		final Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, alarm.hour);
		cal.set(Calendar.MINUTE, alarm.minutes);
		final String time = AlarmProcessor.formatTime(this, cal);

		// Inflate the custom view and set each TextView's text.
		final View v = inflater.inflate(R.layout.context_menu_header, null);
		TextView textView = (TextView) v.findViewById(R.id.header_time);
		textView.setText(time);
		textView = (TextView) v.findViewById(R.id.header_label);
		textView.setText(alarm.label);

		// Set the custom view on the menu.
		menu.setHeaderView(v);
		// Change the text to "disable" if the alarm is already enabled.
		if (alarm.enabled) {
			menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
		}
	}

	@Override
	public boolean onContextItemSelected(final MenuItem item) {
		final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		final int id = (int) info.id;
		switch (item.getItemId()) {
			case R.id.delete_alarm :
				// Confirm that the alarm will be deleted.
				new AlertDialog.Builder(this)
						.setTitle(getString(R.string.delete_alarm))
						.setMessage(getString(R.string.delete_alarm_confirm))
						.setPositiveButton(android.R.string.ok,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface d, int w) {
										AlarmProcessor.deleteAlarm(
												AlarmClock.this, id);
										updateLayout();
									}
								})
						.setNegativeButton(android.R.string.cancel, null)
						.show();
				return true;

			case R.id.enable_alarm :
				final Cursor c = (Cursor) mAlarmsList.getAdapter().getItem(
						info.position);
				final AlarmObject alarm = new AlarmObject(c);
				AlarmProcessor.enableAlarm(this, alarm.id, !alarm.enabled);
				if (!alarm.enabled) {
					SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
							alarm.daysOfWeek);
				}
				updateLayout();
				return true;

			default :
				break;
		}
		return super.onContextItemSelected(item);
	}

//	@Override
//	public boolean onCreateOptionsMenu(Menu menu) {
//		// Inflate our menu.
//		getMenuInflater().inflate(R.menu.alarm_list_menu, menu);
//
//		return super.onCreateOptionsMenu(menu);
//	}

//	@Override
//	public boolean onPrepareOptionsMenu(Menu menu) {
//		menu.findItem(R.id.menu_add_alarm).setVisible(
//				mAlarmsList.getAdapter().getCount() < MAX_ALARM_COUNT);
//
//		return super.onPrepareOptionsMenu(menu);
//	}

//	@Override
//	public boolean onOptionsItemSelected(MenuItem item) {
//		switch (item.getItemId()) {
//			case R.id.menu_add_alarm :
//				Uri uri = AlarmProcessor.addAlarm(getContentResolver());
//				// TODO: Create new alarm _after_ SetAlarm so the user has the
//				// chance to cancel alarm creation.
//				String segment = uri.getPathSegments().get(1);
//				int newId = Integer.parseInt(segment);
//				if (Tools.DEBUG) {
//					Log.v(LOG_CLASS, "In AlarmClock, new alarm id = " + newId);
//				}
//				Intent intent = new Intent(this, SetAlarm.class);
//				intent.putExtra(AlarmProcessor.ALARM_ID, newId);
//				startActivity(intent);
//				return true;
//
//			case R.id.menu_settings :
//				// startActivity(new Intent(this, SettingsActivity.class));
//				return true;
//		}
//
//		return super.onOptionsItemSelected(item);
//	}

	private class AlarmAdapter extends BaseAdapter {
		Cursor cursor;
		// column indexes

		public void updateCursor(Cursor cursor) {
			this.cursor = cursor;
			notifyDataSetChanged();
		}

		@Override
		public int getCount() {
			if (cursor == null) {
				return 0;
			}
			return cursor.getCount();
		}

		@Override
		public Object getItem(int position) {
			if (cursor == null) {
				return null;
			}
			if (cursor.moveToPosition(position)) {
				return cursor;
			}
			return null;
		}

		@Override
		public long getItemId(int position) {
			if (cursor == null) {
				return 0;
			}
			if (cursor.moveToPosition(position)) {
				return cursor
						.getInt(com.alarmtoexercise.util.Data.AlarmColumns.ALARM_ID_INDEX);
			}
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			if (!cursor.moveToPosition(position)) {
				return null;
			}

			final AlarmObject alarm = new AlarmObject(cursor);

			View v = convertView;
			if (v == null) {
				// bind ui
				v = inflater.inflate(R.layout.listitem_alarm_clock, null);

				AlarmItemHolder holder = new AlarmItemHolder();

				holder.cbEnabled = (CheckBox) v.findViewById(R.id.cb_enabled);
				holder.tvTime = (TextView) v.findViewById(R.id.tv_time);
				holder.tvTitle = (TextView) v.findViewById(R.id.tv_title);
				holder.tvDays = (TextView) v.findViewById(R.id.tv_days);

				v.setTag(holder);
			}

			// set ui data
			AlarmItemHolder holder = (AlarmItemHolder) v.getTag();

			holder.cbEnabled.setChecked(alarm.enabled);
			holder.cbEnabled.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					boolean isChecked = ((CheckBox) v).isChecked();
					AlarmProcessor.enableAlarm(AlarmClock.this, alarm.id,
							isChecked);
					if (isChecked) {
						SetAlarm.popAlarmSetToast(AlarmClock.this, alarm.hour,
								alarm.minutes, alarm.daysOfWeek);
					}
				}
			});

			// set the alarm text
			final Calendar c = Calendar.getInstance();
			c.set(Calendar.HOUR_OF_DAY, alarm.hour);
			c.set(Calendar.MINUTE, alarm.minutes);
			String formattedTime = DateFormat.getTimeFormat(context).format(
					c.getTime());
			holder.tvTime.setText(formattedTime);

			// set Days
			final String daysOfWeekStr = alarm.daysOfWeek.toString(
					AlarmClock.this, false);
			if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
				holder.tvDays.setText(daysOfWeekStr);
				holder.tvDays.setVisibility(View.VISIBLE);
			} else {
				holder.tvDays.setVisibility(View.GONE);
			}

			// set Title

			if (alarm.label != null && alarm.label.length() != 0) {
				holder.tvTitle.setText(alarm.label);
				holder.tvTitle.setVisibility(View.VISIBLE);
			} else {
				holder.tvTitle.setVisibility(View.GONE);
			}

			return v;
		}

	}

	static class AlarmItemHolder {
		CheckBox cbEnabled;
		TextView tvTime, tvTitle, tvDays;
	}

}
